所有網頁的開始
都是要先有框架才能繼續下去
所以呢
今天要把所有應該要看到的東西
一口氣全長出來!
首先
來張腦海浮出的架構長相:
整個網頁總共有 6 個組件
App是整個網頁的根組件,為了後面加上資料流預先準備著。Home是作為起始進入的首頁。OOXX是第一種遊戲的主體組件,暫且先用 State 存放假資料,預計後面會被資料流 Store 取代。OXList單純用來呈現連線遊戲的遊戲畫面,在這裡我把遊戲畫面設置成一個狀態資料來存放。AABB是第二種遊戲的主體組件,暫且先用 State 存放假資料,預計後面會被資料流 Store 取代。ABList用來顯示遊戲的歷史紀錄,方便玩家回顧前面猜過的結果。接著是程式碼:App:
class App extends React.Component{
   render(){
      return (
         <div>
            <Router>
               <div>
                  <h2>Games</h2>
                  <ul>
                     <li><Link to={'/ooxx'}>圈圈叉叉</Link></li>
                     <li><Link to={'/aabb'}>數字猜猜</Link></li>
                     <li><Link to={'/'}>回首頁</Link></li>
                  </ul>
                  <hr/>
                  <Switch>
                     <Route exact path="/" component={Home} />
                     <Route exact path="/ooxx" component={OX} />
                     <Route exact path='/aabb' component={AB} />
                  </Switch>
               </div>
            </Router>
         </div>
      );      
   }
}
透過Router來讓網頁元素變更
就像切換到不同的頁面一般
根據路徑決定要渲染哪個組件
畫面呈現:
接著寫遊戲的主體OX:
class OX extends React.Component{
   constructor(){
      super();
      this.state={
         game:[
            {
               "L":"X",
               "C":"O",
               "R":"O",               
            },
            {
               "L":"O",
               "C":"X",
               "R":"O",               
            },
            {
               "L":"O",
               "C":"O",
               "R":"X",               
            }
         ]
      }
   }
   render(){
      return(
         <div>
            <p>先連線,先勝利!</p>
            <table>
               <tbody>
                  {this.state.game.map(
                     (data, i) => <OXList data={data} key={i} />
                     )}
               </tbody>
            </table>
         </div>      
      );
   }
}
為了先看到目前的長相
暫時用假的狀態資料在裡面
目的是要確定有成功的呈現資料出來
在這邊我透過map()函式去把資料一列一列用表格呈現
並且把每一列資料當成另外一個組件OXList:
function OXList(props){
   console.log(props)
   return(
      <tr>
         <td>{props.data.L}</td>
         <td>{props.data.C}</td>
         <td>{props.data.R}</td>
      </tr>
      );
}
因為這個組件只是用來呈現資料
故我使用沒有帶狀態的函式型組件寫法
畫面呈現:
猜數字遊戲的撰寫原理相似
也是一個主體組件乘載資料
然後基於猜數字需要參考前面猜過的數字組合結果
所以將其歷史紀錄設定為一個狀態資料
用另一個組件做單純的呈現
不同的是
這次使用的不是表格
取而代之有一個按鈕存在
作為之後輸入完成後遞交答案的功能位置AB:
class AB extends React.Component{
    constructor(){
        super();
        this.state={
            history:[
                {
                    "Ans":"1234",
                    "A":0,
                    "B":0
                },
                {
                    "Ans":"1234",
                    "A":0,
                    "B":0
                },
                {
                    "Ans":"1234",
                    "A":0,
                    "B":0
                },
            ]
        }
        this.checkAns = this.checkAns.bind(this);
    }
    checkAns(){
        console.log("check clicked!")
    }
    render(){
        return(
            <div>
                <p>數字對位置對為A / 數字對位置錯為B</p>
                <input type="text" placeholder="請輸入4位不重複數字"/>
                <input type="button" value="確認" onClick={this.checkAns}/>
                <div>
                    <p>歷史紀錄:</p>
                    {this.state.history.map(
                       (history, i) => <ABList key={i} data={history} />
                       )}
                </div>
            </div>
            );
    }
}
ABList:
function ABList(props){
    return(
        <p>{props.data.Ans}:{props.data.A}A{props.data.B}B</p>
        );
}
畫面呈現:
以上就是今天整個外觀的產生過程紀錄
感覺自己又更上手一點點了呢
接續幾天都要繼續加油!

- Eva Vue.js 30天隨身包
- Ben那些年,我們一起錯過的Javascript
- Ray激戰ReactJS 30天
Day23 end
by 瑞Ray (つ´ω`)つ